import * as XLSX from 'xlsx'
import dayjs from 'dayjs'

/**
 * 导出甘特图数据到Excel
 * @param {Array} tasks - 任务数据数组
 * @param {Object} timeline - 时间轴信息
 * @param {Object} statistics - 统计信息
 * @param {String} filename - 文件名
 */
export const exportToExcel = (tasks, timeline, statistics, filename = null) => {
  // 创建工作簿
  const workbook = XLSX.utils.book_new()
  
  // 准备任务数据
  const taskData = prepareTaskData(tasks)
  
  // 准备统计数据
  const statisticsData = prepareStatisticsData(statistics, timeline)
  
  // 创建工作表
  const taskWorksheet = XLSX.utils.json_to_sheet(taskData)
  const statisticsWorksheet = XLSX.utils.json_to_sheet(statisticsData)
  
  // 设置列宽
  const taskColWidths = [
    { wch: 30 }, // 任务名称
    { wch: 15 }, // 负责人
    { wch: 12 }, // 开始时间
    { wch: 12 }, // 结束时间
    { wch: 8 },  // 进度
    { wch: 10 }, // 优先级
    { wch: 10 }, // 状态
    { wch: 15 }, // 前置任务
    { wch: 8 },  // 层级
    { wch: 10 }, // 持续时间
    { wch: 20 }  // 备注
  ]
  
  const statisticsColWidths = [
    { wch: 20 }, // 统计项
    { wch: 15 }  // 数值
  ]
  
  taskWorksheet['!cols'] = taskColWidths
  statisticsWorksheet['!cols'] = statisticsColWidths
  
  // 添加工作表到工作簿
  XLSX.utils.book_append_sheet(workbook, taskWorksheet, '任务列表')
  XLSX.utils.book_append_sheet(workbook, statisticsWorksheet, '统计信息')
  
  // 生成文件名
  const defaultFilename = `甘特图数据_${dayjs().format('YYYY-MM-DD_HH-mm-ss')}.xlsx`
  const finalFilename = filename || defaultFilename
  
  // 导出文件
  XLSX.writeFile(workbook, finalFilename)
  
  return finalFilename
}

/**
 * 准备任务数据
 * @param {Array} tasks - 原始任务数据
 * @returns {Array} 格式化后的任务数据
 */
const prepareTaskData = (tasks) => {
  return tasks.map(task => {
    const startDate = dayjs(task.startDate)
    const endDate = dayjs(task.endDate)
    const duration = endDate.diff(startDate, 'day') + 1
    
    return {
      '任务名称': getTaskNameWithLevel(task),
      '负责人': task.assignee || '未分配',
      '开始时间': startDate.format('YYYY-MM-DD'),
      '结束时间': endDate.format('YYYY-MM-DD'),
      '进度(%)': task.progress || 0,
      '优先级': getPriorityText(task.priority),
      '状态': getStatusText(task.status),
      '前置任务': getDependencyText(task.dependencies),
      '层级': task.level || 0,
      '持续时间(天)': duration,
      '备注': getTaskNotes(task)
    }
  })
}

/**
 * 准备统计数据
 * @param {Object} statistics - 统计信息
 * @param {Object} timeline - 时间轴信息
 * @returns {Array} 格式化后的统计数据
 */
const prepareStatisticsData = (statistics, timeline) => {
  return [
    { '统计项': '总任务数', '数值': statistics.totalTasks },
    { '统计项': '显示任务数', '数值': statistics.visibleTasks },
    { '统计项': '已完成任务数', '数值': statistics.completedTasks },
    { '统计项': '进行中任务数', '数值': statistics.inProgressTasks },
    { '统计项': '待开始任务数', '数值': statistics.pendingTasks },
    { '统计项': '平均进度(%)', '数值': statistics.totalProgress },
    { '统计项': '时间范围开始', '数值': timeline.start },
    { '统计项': '时间范围结束', '数值': timeline.end },
    { '统计项': '导出时间', '数值': dayjs().format('YYYY-MM-DD HH:mm:ss') }
  ]
}

/**
 * 获取带层级的任务名称
 * @param {Object} task - 任务对象
 * @returns {String} 格式化后的任务名称
 */
const getTaskNameWithLevel = (task) => {
  const indent = '  '.repeat(task.level || 0)
  return indent + (task.name || '未知任务')
}

/**
 * 获取优先级文本
 * @param {String} priority - 优先级
 * @returns {String} 优先级文本
 */
const getPriorityText = (priority) => {
  const priorityMap = {
    'high': '高',
    'medium': '中',
    'low': '低'
  }
  return priorityMap[priority] || '中'
}

/**
 * 获取状态文本
 * @param {String} status - 状态
 * @returns {String} 状态文本
 */
const getStatusText = (status) => {
  const statusMap = {
    'pending': '待开始',
    'in-progress': '进行中',
    'completed': '已完成',
    'cancelled': '已取消'
  }
  return statusMap[status] || '待开始'
}

/**
 * 获取依赖任务文本
 * @param {Array} dependencies - 依赖任务ID数组
 * @returns {String} 依赖任务文本
 */
const getDependencyText = (dependencies) => {
  if (!dependencies || dependencies.length === 0) {
    return '无'
  }
  return dependencies.join(', ')
}

/**
 * 获取任务备注
 * @param {Object} task - 任务对象
 * @returns {String} 任务备注
 */
const getTaskNotes = (task) => {
  const notes = []
  
  if (task.color && task.color !== '#409EFF') {
    notes.push(`颜色: ${task.color}`)
  }
  
  if (task.parentId) {
    notes.push(`上级任务: ${task.parentId}`)
  }
  
  return notes.join('; ')
}

/**
 * 导出任务时间线到Excel（按时间顺序）
 * @param {Array} tasks - 任务数据数组
 * @param {String} filename - 文件名
 */
export const exportTimelineToExcel = (tasks, filename = null) => {
  // 创建工作簿
  const workbook = XLSX.utils.book_new()
  
  // 按开始时间排序
  const sortedTasks = [...tasks].sort((a, b) => {
    return dayjs(a.startDate).diff(dayjs(b.startDate))
  })
  
  // 准备时间线数据
  const timelineData = sortedTasks.map(task => {
    const startDate = dayjs(task.startDate)
    const endDate = dayjs(task.endDate)
    
    return {
      '开始日期': startDate.format('YYYY-MM-DD'),
      '结束日期': endDate.format('YYYY-MM-DD'),
      '任务名称': getTaskNameWithLevel(task),
      '负责人': task.assignee || '未分配',
      '进度(%)': task.progress || 0,
      '优先级': getPriorityText(task.priority),
      '状态': getStatusText(task.status),
      '持续时间(天)': endDate.diff(startDate, 'day') + 1
    }
  })
  
  // 创建工作表
  const worksheet = XLSX.utils.json_to_sheet(timelineData)
  
  // 设置列宽
  const colWidths = [
    { wch: 12 }, // 开始日期
    { wch: 12 }, // 结束日期
    { wch: 30 }, // 任务名称
    { wch: 15 }, // 负责人
    { wch: 8 },  // 进度
    { wch: 10 }, // 优先级
    { wch: 10 }, // 状态
    { wch: 12 }  // 持续时间
  ]
  
  worksheet['!cols'] = colWidths
  
  // 添加工作表到工作簿
  XLSX.utils.book_append_sheet(workbook, worksheet, '时间线')
  
  // 生成文件名
  const defaultFilename = `甘特图时间线_${dayjs().format('YYYY-MM-DD_HH-mm-ss')}.xlsx`
  const finalFilename = filename || defaultFilename
  
  // 导出文件
  XLSX.writeFile(workbook, finalFilename)
  
  return finalFilename
}

/**
 * 导出项目报告到Excel
 * @param {Array} tasks - 任务数据数组
 * @param {Object} timeline - 时间轴信息
 * @param {Object} statistics - 统计信息
 * @param {String} filename - 文件名
 */
export const exportProjectReportToExcel = (tasks, timeline, statistics, filename = null) => {
  // 创建工作簿
  const workbook = XLSX.utils.book_new()
  
  // 1. 项目概览
  const overviewData = [
    { '项目信息': '项目名称', '数值': '甘特图项目' },
    { '项目信息': '时间范围', '数值': `${timeline.start} 至 ${timeline.end}` },
    { '项目信息': '总任务数', '数值': statistics.totalTasks },
    { '项目信息': '已完成任务', '数值': statistics.completedTasks },
    { '项目信息': '进行中任务', '数值': statistics.inProgressTasks },
    { '项目信息': '待开始任务', '数值': statistics.pendingTasks },
    { '项目信息': '整体进度', '数值': `${statistics.totalProgress}%` },
    { '项目信息': '报告生成时间', '数值': dayjs().format('YYYY-MM-DD HH:mm:ss') }
  ]
  
  // 2. 任务详情
  const taskData = prepareTaskData(tasks)
  
  // 3. 按负责人分组统计
  const assigneeStats = getAssigneeStatistics(tasks)
  
  // 4. 按优先级分组统计
  const priorityStats = getPriorityStatistics(tasks)
  
  // 5. 按状态分组统计
  const statusStats = getStatusStatistics(tasks)
  
  // 创建工作表
  const overviewWorksheet = XLSX.utils.json_to_sheet(overviewData)
  const taskWorksheet = XLSX.utils.json_to_sheet(taskData)
  const assigneeWorksheet = XLSX.utils.json_to_sheet(assigneeStats)
  const priorityWorksheet = XLSX.utils.json_to_sheet(priorityStats)
  const statusWorksheet = XLSX.utils.json_to_sheet(statusStats)
  
  // 设置列宽
  overviewWorksheet['!cols'] = [{ wch: 20 }, { wch: 30 }]
  taskWorksheet['!cols'] = [
    { wch: 30 }, { wch: 15 }, { wch: 12 }, { wch: 12 },
    { wch: 8 }, { wch: 10 }, { wch: 10 }, { wch: 15 },
    { wch: 8 }, { wch: 10 }, { wch: 20 }
  ]
  assigneeWorksheet['!cols'] = [{ wch: 20 }, { wch: 15 }, { wch: 15 }, { wch: 15 }]
  priorityWorksheet['!cols'] = [{ wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }]
  statusWorksheet['!cols'] = [{ wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }]
  
  // 添加工作表到工作簿
  XLSX.utils.book_append_sheet(workbook, overviewWorksheet, '项目概览')
  XLSX.utils.book_append_sheet(workbook, taskWorksheet, '任务详情')
  XLSX.utils.book_append_sheet(workbook, assigneeWorksheet, '负责人统计')
  XLSX.utils.book_append_sheet(workbook, priorityWorksheet, '优先级统计')
  XLSX.utils.book_append_sheet(workbook, statusWorksheet, '状态统计')
  
  // 生成文件名
  const defaultFilename = `项目报告_${dayjs().format('YYYY-MM-DD_HH-mm-ss')}.xlsx`
  const finalFilename = filename || defaultFilename
  
  // 导出文件
  XLSX.writeFile(workbook, finalFilename)
  
  return finalFilename
}

/**
 * 获取按负责人分组的统计
 * @param {Array} tasks - 任务数据数组
 * @returns {Array} 负责人统计数据
 */
const getAssigneeStatistics = (tasks) => {
  const assigneeMap = {}
  
  tasks.forEach(task => {
    const assignee = task.assignee || '未分配'
    if (!assigneeMap[assignee]) {
      assigneeMap[assignee] = {
        '负责人': assignee,
        '总任务数': 0,
        '已完成': 0,
        '进行中': 0,
        '待开始': 0
      }
    }
    
    assigneeMap[assignee]['总任务数']++
    
    switch (task.status) {
      case 'completed':
        assigneeMap[assignee]['已完成']++
        break
      case 'in-progress':
        assigneeMap[assignee]['进行中']++
        break
      case 'pending':
        assigneeMap[assignee]['待开始']++
        break
    }
  })
  
  return Object.values(assigneeMap)
}

/**
 * 获取按优先级分组的统计
 * @param {Array} tasks - 任务数据数组
 * @returns {Array} 优先级统计数据
 */
const getPriorityStatistics = (tasks) => {
  const priorityMap = {
    '高': { '优先级': '高', '总任务数': 0, '已完成': 0, '进行中': 0, '待开始': 0 },
    '中': { '优先级': '中', '总任务数': 0, '已完成': 0, '进行中': 0, '待开始': 0 },
    '低': { '优先级': '低', '总任务数': 0, '已完成': 0, '进行中': 0, '待开始': 0 }
  }
  
  tasks.forEach(task => {
    const priority = getPriorityText(task.priority)
    priorityMap[priority]['总任务数']++
    
    switch (task.status) {
      case 'completed':
        priorityMap[priority]['已完成']++
        break
      case 'in-progress':
        priorityMap[priority]['进行中']++
        break
      case 'pending':
        priorityMap[priority]['待开始']++
        break
    }
  })
  
  return Object.values(priorityMap)
}

/**
 * 获取按状态分组的统计
 * @param {Array} tasks - 任务数据数组
 * @returns {Array} 状态统计数据
 */
const getStatusStatistics = (tasks) => {
  const statusMap = {
    '待开始': { '状态': '待开始', '任务数': 0, '占比(%)': 0 },
    '进行中': { '状态': '进行中', '任务数': 0, '占比(%)': 0 },
    '已完成': { '状态': '已完成', '任务数': 0, '占比(%)': 0 },
    '已取消': { '状态': '已取消', '任务数': 0, '占比(%)': 0 }
  }
  
  tasks.forEach(task => {
    const status = getStatusText(task.status)
    statusMap[status]['任务数']++
  })
  
  const total = tasks.length
  
  Object.values(statusMap).forEach(item => {
    item['占比(%)'] = total > 0 ? Math.round((item['任务数'] / total) * 100) : 0
  })
  
  return Object.values(statusMap)
} 